#ifndef __ENV_CPP__
#define __ENV_CPP__

#include "env.h"
#include "bytearrays.h"
#include "section.h"
#include "output.h"
#include "msghandle.h"
#include "msgqueue.h"

int __rwsize;
char* __rwstring;

namespace WServer {

namespace GData {

struct wserSocketData* clientlist;

//env
std::vector<ModuleData> modulelist;
int logMaxRows;

//common
int moduleindex;
int msghandlethreadcount;
int memorycount;
int servermsglength;
int wmainindex, wmysqlindex, wsocketindex, wphpindex, wsimulatorindex;
int wmainmsgindex, wmysqlmsgindex, wsocketmsgindex, wphpmsgindex, wsimulatormsgindex;
int outputfile, outputconsole;

//wmain
int maxconn;
int maxobject;
int msgextthreadcount;

//wmysql
std::string dbhost;
std::string dbusername;
std::string dbpassword;
std::string dbname;
int handlemysqlcount;
int mysqlconnectioncount;
int mysqlquerylog;
int mysqlsaveplayerdata;

//wsocket
int serverport;
int socketslog, socketrlog;
int socketsendcount, socketrecvcount;

int fsmem;

}	//namespace GData

namespace Env {

void wserInit(int mindex)
{
	GData::gOption = new Section::wserSection("data.xml");

	int pos, i;
	std::string fullname = GData::gOption->GetString("env|modules");
	do {
		pos = fullname.find("|");
		if (pos == std::string::npos) {
			GData::modulelist.push_back(GData::ModuleData(fullname, 0));
			break;
		}
		GData::modulelist.push_back(GData::ModuleData(fullname.substr(0, pos), 0));
		fullname = fullname.substr(pos+1, fullname.length()-pos);
	}
	while (1);

	GData::logMaxRows = GData::gOption->GetInteger("env|LogMaxRows");
	std::string modulename = modulelist[moduleindex].modulename;

	GData::msghandlethreadcount = GData::gOption->GetInteger(modulename+"|MsgHandleThreadCount");
	GData::memorycount = GData::gOption->GetInteger(modulename+"|MemoryCount");
	GData::wmainindex = GData::gOption->GetInteger("wmain|id");GData::wmainmsgindex = 1<<GData::wmainindex;
	GData::wmysqlindex = GData::gOption->GetInteger("wmysql|id");GData::wmysqlmsgindex = 1<<GData::wmysqlindex;
	GData::wsocketindex = GData::gOption->GetInteger("wsocket|id");GData::wsocketmsgindex = 1<<GData::wsocketindex;
	GData::wphpindex = GData::gOption->GetInteger("wphp|id");GData::wphpmsgindex = 1<<GData::wphpindex;
	GData::wsimulatorindex = GData::gOption->GetInteger("wsimulator|id");GData::wsimulatormsgindex = 1<<GData::wsimulatorindex;
	GData::outputfile = GData::gOption->GetInteger("env|OutputFile");
	GData::outputconsole = GData::gOption->GetInteger("env|OutputConsole");

	GData::maxconn = GData::gOption->GetInteger("wmain|MaxPlayer");
	GData::maxobject = GData::gOption->GetInteger("wmain|MaxObject");
	GData::msgextthreadcount = GData::gOption->GetInteger("wmain|MsgExtThreadCount");

	GData::dbhost = GData::gOption->GetString("wmysql|host");
	GData::dbusername = GData::gOption->GetString("wmysql|username");
	GData::dbpassword = GData::gOption->GetString("wmysql|password");if (GData::dbpassword == " ") GData::dbpassword = "";
	GData::dbname = GData::gOption->GetString("wmysql|dbname");
	GData::handlemysqlcount = GData::gOption->GetInteger("wmysql|HandleMySQLCount");
	GData::mysqlconnectioncount = GData::gOption->GetInteger("wmysql|MySQLConnectionCount"); if (GData::mysqlconnectioncount == 0) GData::mysqlconnectioncount = 1;
	GData::mysqlquerylog = GData::gOption->GetInteger("wmysql|MySQLQueryLog");
	GData::mysqlsaveplayerdata = GData::gOption->GetInteger("wmysql|SavePlayerData");

	GData::serverport = GData::gOption->GetInteger("wsocket|BasePort");
	GData::socketslog = GData::gOption->GetInteger("wsocket|SocketSendLog");
	GData::socketrlog = GData::gOption->GetInteger("wsocket|SocketRecvLog");
	GData::socketsendcount = GData::gOption->GetInteger("wsocket|SocketSendCount");
	GData::socketrecvcount = GData::gOption->GetInteger("wsocket|SocketRecvCount");

	if (mindex == wmainindex) GData::servermsglength = GData::msgextthreadcount;
	if (mindex == wsocketindex) GData::servermsglength = GData::socketsendcount;
	if (mindex == wmysqlindex) GData::servermsglength = GData::handlemysqlcount;
	if (mindex == wsimulatorindex) GData::servermsglength = 1;

	MemoryPool::instance()->initMemoryPool();

	GData::fsmem = open("smem",O_RDWR);
	char* buf = new char[sizeof(struct GData::wserSocketData)];
	try {
		for (int i = 0;i < GData::maxconn;i++) {
			__rwsize = read(GData::fsmem, buf, sizeof(struct GData::wserSocketData));
		}
	}
	catch (...) {
		printf("read(GData::fsmem\n");
	}
	delete[] buf;buf = 0;

	Output::wserInitOutput();
	MsgHandle::wserInitMsgHandle(mindex);
	MsgQueue::wserInitMsgQueue(mindex);

	if (MAP_FAILED == GData::clientlist) {
		printf("GData::clientlist-%d\n",errno);
		exit(0);
	}
}

void wserUninit()
{
	munmap(GData::clientlist, sizeof(struct GData::wserSocketData)*GData::maxconn);
	close(GData::fsmem);
	MsgQueue::wserUninitMsgQueue();
	MsgHandle::wserUninitMsgHandle();
	Output::wserUninitOutput();
	if (GData::gOption) {
		delete GData::gOption;
		GData::gOption = NULL;
	}
	wserPrintMsg("exit....\n");
}

void initSocketData(int index)
{
	GData::clientlist[index].hclient = -1;
	GData::clientlist[index].status = 0;
	GData::clientlist[index].ip.s_addr = 0;
	GData::clientlist[index].port = 0;
	GData::clientlist[index].objectid = 0;
}


} //namespace Env

} //namespace WServer

#endif //__ENV_CPP__
